home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1998 July / EnigmA AMIGA RUN 29 (1998)(G.R. Edizioni)(IT)[!][issue 1998-07 & 08].iso / recent / gms_pi.lha / Pictures / PIC_Init.c < prev    next >
C/C++ Source or Header  |  1998-06-22  |  13KB  |  448 lines

  1.  
  2. #include <proto/dpkernel.h>
  3. #include <system/all.h>
  4. #include <dpkernel/prefs.h>
  5. #include "defs.h"
  6.  
  7. /************************************************************************************
  8. ** Action: CheckFile()
  9. ** Object: Picture
  10. */
  11.  
  12. LIBFUNC LONG PIC_CheckFile(mreg(__a0) struct File *File,
  13.                            mreg(__a1) LONG *Buffer)
  14. {
  15.   if (Buffer[0] IS CODE_FORM AND Buffer[2] IS CODE_ILBM) {
  16.      DPrintF("CheckFile:","File identified as Picture");
  17.      return(99);
  18.   }
  19.   else {
  20.      return(NULL);
  21.   }
  22. }
  23.  
  24. /************************************************************************************
  25. ** Action: Free()
  26. ** Object: Picture
  27. */
  28.  
  29. LIBFUNC void PIC_Free(mreg(__a0) struct Picture *pic)
  30. {
  31.   FreeMemBlock(pic->prvData);
  32.   FreeMemBlock(pic->prvPalette);
  33.   Free(pic->Bitmap);
  34.  
  35.   FreeMemBlock(pic);
  36.   PictureMod->Public->OpenCount--;
  37. }
  38.  
  39. /************************************************************************************
  40. ** Action: Get()
  41. ** Object: Picture
  42. */
  43.  
  44. LIBFUNC struct Picture * PIC_Get(mreg(__a0) struct Stats *Stats)
  45. {
  46.   struct Picture *Picture;
  47.  
  48.   if (Picture = AllocMemBlock(sizeof(struct Picture), Stats->MemFlags|MEM_DATA|MEM_UNTRACKED)) {
  49.      Picture->Head.ID      = ID_PICTURE;
  50.      Picture->Head.Version = VER_PICTURE;
  51.  
  52.      if (Picture->Bitmap = Get(ID_BITMAP|GET_NOTRACK)) {
  53.         Picture->Bitmap->Parent = Picture;
  54.         PictureMod->Public->OpenCount++;
  55.         return(Picture);
  56.      }
  57.      else DPrintF("!Get:","Failed to obtain a Bitmap for this Picture.");
  58.  
  59.      FreeMemBlock(Picture);
  60.   }
  61.   else ErrCode(ERR_MEMORY);
  62.  
  63.   return(NULL);
  64. }
  65.  
  66. /************************************************************************************
  67. ** Action: Init()
  68. ** Object: Picture
  69. **
  70. ** Loads in a picture, automatically depacking it, assessing the info header and
  71. ** then copying it out to the bitmap.
  72. */
  73.  
  74. LIBFUNC LONG PIC_Init(mreg(__a0) struct Picture *Picture)
  75. {
  76.   struct File *File = NULL;
  77.   struct BMHD *BMHD = NULL;
  78.   LONG BodyPos  = NULL;
  79.   LONG CAMG     = NULL;
  80.   LONG *CMAP    = NULL;
  81.   LONG *Buffer  = NULL;
  82.   LONG error    = ERR_FAILED;
  83.   APTR FILBase  = GVBase->FileBase;    /* Seek() and OpenFile() */
  84.   WORD FreeFile = FALSE;
  85.   LONG FileSize;
  86.  
  87.   /* Open the file and allocate a read buffer.  Note that we check
  88.   ** if the Picture->Source is an initialised File, because we do
  89.   ** not want to open the file twice (illegal).
  90.   */
  91.  
  92.   if (((struct Head *)Picture->Source)->ID IS ID_FILE) {
  93.      if (CheckInit(Picture->Source) IS TRUE) {
  94.         File = Picture->Source;
  95.      }
  96.   }
  97.  
  98.   if (File IS NULL) {
  99.      if ((File = OpenFile(Picture->Source,FL_READ)) IS NULL) {
  100.         error = ErrCode(ERR_FILE);
  101.         goto exit;
  102.      }
  103.      else FreeFile = TRUE;
  104.   }
  105.  
  106.   Buffer = AllocMemBlock(BUFFERSIZE,MEM_DATA); /* Allocate a 4k buffer */
  107.  
  108.   /*** Check for the initial FORM/ILBM part ***/
  109.  
  110.   Seek(File, 0, POS_START); /* Required in case Picture->Source has been used */
  111.   Read(File, Buffer, 12);   /* [FORM] [Size] [ILBM] */
  112.   if ((Buffer[0] != CODE_FORM) OR (Buffer[2] != CODE_ILBM)) {
  113.      DPrintF("!Init:","This file does not start with a FORM/ILBM header.");
  114.      error = ERR_DATA;
  115.      goto exit;
  116.   }
  117.  
  118.   FileSize = Buffer[1];
  119.  
  120.   /*** Read each iff chunk in the file ***/
  121.  
  122.   while ((FileSize > 0) AND (BodyPos IS NULL)) {
  123.      if (Read(File,Buffer,8) != 8) { /* [CODE] [Size] */
  124.         DPrintF("!Query","I could not read the next chunk.");
  125.         goto exit;
  126.      }
  127.  
  128.      if (Buffer[1] & 0x00000001) Buffer[1] += 1;
  129.  
  130.      FileSize -= Buffer[1];
  131.  
  132.      if (Buffer[0] IS CODE_CMAP) {
  133.         DPrintF("Init:","IFF CMAP header found.");
  134.         if (Buffer[1] > BUFFERSIZE) goto exit;
  135.         if (CMAP = AllocMemBlock(Buffer[1],MEM_DATA)) {
  136.            Read(File, CMAP, Buffer[1]);
  137.         }
  138.      }
  139.      else if (Buffer[0] IS CODE_BMHD) {
  140.         DPrintF("Init:","IFF BMHD header found.");
  141.         if (Buffer[1] > BUFFERSIZE) goto exit;
  142.         if (BMHD = AllocMemBlock(Buffer[1],MEM_DATA)) {
  143.            if (Read(File, BMHD, Buffer[1]) != Buffer[1]) {
  144.               error = ErrCode(ERR_READ);
  145.               goto exit;
  146.            }
  147.         }
  148.         else {
  149.            error = ErrCode(ERR_MEMORY);
  150.            goto exit;
  151.         }
  152.      }
  153.      else if (Buffer[0] IS CODE_CAMG) {
  154.         DPrintF("Init:","IFF CAMG header found.");
  155.         if (Buffer[1] > BUFFERSIZE) goto exit;
  156.         if (Read(File,Buffer,Buffer[1]) IS Buffer[1]) {
  157.            CAMG = Buffer[0];
  158.         }
  159.         else {
  160.            error = ErrCode(ERR_READ);
  161.            goto exit;
  162.         }
  163.      }
  164.      else if (Buffer[0] IS CODE_BODY) {
  165.         DPrintF("Init:","IFF BODY header found.");
  166.         BodyPos = File->BytePos;
  167.      }
  168.      else {
  169.         if (Seek(File, Buffer[1], POS_CURRENT) IS -1) { /* Skip to the next chunk */
  170.             DPrintF("!Init:","I could not seek to the correct file position.");
  171.             goto exit;
  172.         }
  173.      }
  174.   }
  175.  
  176.   if (BodyPos) {
  177.      /* Calling a query on the picture will give us an initialised
  178.      ** Bitmap that we can play with.
  179.      */
  180.  
  181.      if (Query(Picture) IS ERR_OK) {
  182.         if (Picture->Bitmap->Data IS NULL) {
  183.            DPrintF("Init:","Allocating Bitmap data space.");
  184.            if (!(Picture->Bitmap->Data = AllocMemBlock(Picture->Bitmap->Size, Picture->Bitmap->MemType))) {
  185.               DPrintF("!Init:","Could not allocate Bitmap data space.");
  186.               return(NULL);
  187.            }
  188.            Picture->prvData = Picture->Bitmap->Data;
  189.         }
  190.  
  191.         Seek(File, BodyPos, POS_START);
  192.  
  193.         error = UnpackPicture(Picture,BMHD,File,CMAP,CAMG);
  194.      }
  195.      else DPrintF("!Init:","Could not query picture information.");
  196.   }
  197.   else DPrintF("!Init:","Picture has no BODY chunk.");
  198.  
  199. exit:
  200.   if (Buffer) FreeMemBlock(Buffer);
  201.   if (BMHD)   FreeMemBlock(BMHD);
  202.   if (CMAP)   FreeMemBlock(CMAP);
  203.   if (FreeFile IS TRUE) Free(File);
  204.   return(error);
  205. }
  206.  
  207. /************************************************************************************
  208. ** Action: Load()
  209. ** Object: Picture
  210. **
  211. ** Loads in an object file that is known to be of the Picture class.  This action
  212. ** will get the palette of the Picture if there is one, and store the data in
  213. ** standard memory.
  214. **
  215. ** We use the File->Source rather than just the File, because we must assume
  216. ** that the File object will be freed by Load() and only the source will continue
  217. ** to be valid.
  218. */
  219.  
  220. LIBFUNC struct Picture * PIC_Load(mreg(__a0) struct File *File)
  221. {
  222.   struct Picture *Picture;
  223.  
  224.   Picture = InitTags(NULL,
  225.     TAGS_PICTURE, NULL,
  226.     PCA_Source,   File->Source,
  227.     TAGEND);
  228.  
  229.   return(Picture);
  230. }
  231.  
  232. /************************************************************************************
  233. ** Action: Query()
  234. ** Object: Picture
  235. **
  236. ** Gets picture information - width, height, amount of colors, planes etc.  It does
  237. ** not grab the data of the picture.
  238. */
  239.  
  240. LIBFUNC LONG PIC_Query(mreg(__a0) struct Picture *Picture)
  241. {
  242.   struct BMHD   *BMHD   = NULL;
  243.   struct File   *File   = NULL;
  244.   struct Bitmap *Bitmap;
  245.   LONG   error    = ERR_FAILED; /* The default code is for failure */
  246.   LONG   CAMG     = NULL;
  247.   LONG   *CMAP    = NULL;
  248.   LONG   CMAPSize = NULL;       /* Size of the CMAP array */
  249.   LONG   *Buffer  = NULL;
  250.   WORD   FreeFile = FALSE;
  251.   APTR   BLTBase  = GVBase->BlitterBase; /* GetBmpType() */
  252.   APTR   FILBase  = GVBase->FileBase;    /* Seek() and OpenFile() */
  253.   BYTE   *SrcPalette;
  254.   BYTE   *DestPalette;
  255.   LONG   i;
  256.   APTR   Temp;
  257.   LONG   FileSize;
  258.  
  259.   DPrintF("~Query()","Picture: $%x", Picture);
  260.  
  261.   /*** Validation procedures ***/
  262.  
  263.   if ((Bitmap = Picture->Bitmap) IS NULL) {
  264.      DPrintF("!Query;","No Picture->Bitmap present.");
  265.      goto exit;
  266.   }
  267.  
  268.   /* Open the file and allocate a read buffer.  Note that we check
  269.   ** if the Picture->Source is an initialised File, because we do
  270.   ** not want to open the file twice (illegal).
  271.   */
  272.  
  273.   if (((struct Head *)Picture->Source)->ID IS ID_FILE) {
  274.      if (CheckInit(Picture->Source) IS TRUE) {
  275.         File = Picture->Source;
  276.      }
  277.   }
  278.  
  279.   if (File IS NULL) {
  280.      if ((File = OpenFile(Picture->Source,FL_READ)) IS NULL) {
  281.         error = ErrCode(ERR_FILE);
  282.         goto exit;
  283.      }
  284.      else FreeFile = TRUE;
  285.   }
  286.  
  287.   Buffer = AllocMemBlock(BUFFERSIZE,MEM_DATA); /* Allocate a 4k buffer */
  288.  
  289.   /*** Check for the initial FORM/ILBM part ***/
  290.  
  291.   Seek(File, 0, POS_START); /* Required in case Picture->Source has been used */
  292.   Read(File, Buffer, 12);   /* [FORM] [Size] [ILBM] */
  293.   if ((Buffer[0] != CODE_FORM) OR (Buffer[2] != CODE_ILBM)) {
  294.      DPrintF("!Query:","This file does not start with a FORM/ILBM header.");
  295.      error = ERR_DATA;
  296.      goto exit;
  297.   }
  298.  
  299.   FileSize = GetFSize(File);
  300.  
  301.   /*** Read each iff chunk in the file ***/
  302.  
  303.   while (File->BytePos < FileSize) {
  304.      if (Read(File,Buffer,8) != 8) { /* [CODE] [Size] */
  305.         DPrintF("!Query:","I could not read the next chunk.");
  306.         break;
  307.      }
  308.  
  309.      if (Buffer[1] & 0x00000001) Buffer[1] += 1;
  310.  
  311.      if (Buffer[0] IS CODE_CMAP) {
  312.         DPrintF("Query:","IFF CMAP header found.");
  313.         if (Buffer[1] > BUFFERSIZE) goto exit;
  314.  
  315.         CMAPSize = Buffer[1]/3;
  316.         if (CMAP = AllocMemBlock(Buffer[1],MEM_DATA)) {
  317.            Read(File, CMAP, Buffer[1]);
  318.         }
  319.      }
  320.      else if (Buffer[0] IS CODE_BMHD) {
  321.         DPrintF("Query:","IFF BMHD header found.");
  322.         if (Buffer[1] > BUFFERSIZE) goto exit;
  323.         if (BMHD = AllocMemBlock(Buffer[1],MEM_DATA)) {
  324.            if (Read(File, BMHD, Buffer[1]) != Buffer[1]) {
  325.               error = ErrCode(ERR_READ);
  326.               goto exit;
  327.            }
  328.         }
  329.         else {
  330.            error = ErrCode(ERR_MEMORY);
  331.            goto exit;
  332.         }
  333.      }
  334.      else if (Buffer[0] IS CODE_CAMG) {
  335.         DPrintF("Query:","IFF CAMG header found.");
  336.         if (Buffer[1] > BUFFERSIZE) goto exit;
  337.         if (Read(File,Buffer,Buffer[1]) IS Buffer[1]) {
  338.            CAMG = Buffer[0];
  339.         }
  340.         else {
  341.            error = ErrCode(ERR_READ);
  342.            goto exit;
  343.         }
  344.      }
  345.      else {
  346.         DPrintF("Query:","Unused chunk, skipping %ld bytes.",Buffer[1]);
  347.         if (Seek(File, Buffer[1], POS_CURRENT) IS -1) { /* Skip to the next chunk */
  348.             DPrintF("!Query:","I could not seek to the correct file position.");
  349.             goto exit;
  350.         }
  351.      }
  352.   }
  353.  
  354.   if (BMHD) {
  355.      if (Bitmap->AmtColours IS NULL) Bitmap->AmtColours = CMAPSize;
  356.      if (Bitmap->Height IS NULL)     Bitmap->Height     = BMHD->Height;
  357.      if (Bitmap->Planes IS NULL)     Bitmap->Planes     = BMHD->Depth;
  358.      if (Bitmap->Type IS NULL)       Bitmap->Type       = GetBmpType(); /* User preference */
  359.      if (Picture->ScrWidth IS NULL)  Picture->ScrWidth  = BMHD->ScrWidth;
  360.      if (Picture->ScrHeight IS NULL) Picture->ScrHeight = BMHD->ScrHeight;
  361.      if (Bitmap->Width IS NULL) {
  362.         Bitmap->Width     = BMHD->Width;
  363.         Bitmap->ByteWidth = NULL;        /* Let the Init(Bitmap) calculate it */
  364.      }
  365.   }
  366.  
  367.   if (CAMG) {
  368.      /* Note that if the programmer has preset a non-planar mode,
  369.      ** then we cannot set HAM or EHB bits (the picture will be
  370.      ** converted so special graphic flags do not apply).
  371.      */
  372.  
  373.      if ((Bitmap->Type IS ILBM) OR (Bitmap->Type IS PLANAR)) {
  374.         if ((Bitmap->Planes IS 6) OR (Bitmap->Planes IS 8)) {
  375.            if (CAMG & OSV_HAM) Picture->Bitmap->Flags |= BMF_HAM;
  376.            if (CAMG & OSV_EHB) Picture->Bitmap->Flags |= BMF_EXTRAHB;
  377.         }
  378.      }
  379.  
  380.      if (CAMG & OSV_LACED) Picture->ScrMode |= SM_LACED;
  381.      if (CAMG & OSV_HIRES) {
  382.         Picture->ScrMode |= SM_HIRES;
  383.      }
  384.      else Picture->ScrMode |= SM_LORES;
  385.   }
  386.  
  387.   /*** Generate Palette ***/
  388.  
  389.   if ((Bitmap->Palette IS NULL) AND (Bitmap->AmtColours <= 256) AND (CMAP)) {
  390.      if (Bitmap->Palette = AllocMemBlock((Bitmap->AmtColours * 4)+8,MEM_DATA)) {
  391.         Picture->prvPalette = Bitmap->Palette;
  392.         Bitmap->Palette[0]  = PALETTE_ARRAY;
  393.         Bitmap->Palette[1]  = Bitmap->AmtColours;
  394.         SrcPalette          = (BYTE *)CMAP;
  395.         DestPalette         = ((BYTE *)Bitmap->Palette)+8;
  396.         for (i=0; i < Bitmap->AmtColours; i++) {
  397.            DestPalette[1] = SrcPalette[0];
  398.            DestPalette[2] = SrcPalette[1];
  399.            DestPalette[3] = SrcPalette[2];
  400.            DestPalette += 4;
  401.            SrcPalette  += 3;
  402.         }
  403.      }
  404.      else {
  405.         error = ErrCode(ERR_MEMORY);
  406.         goto exit;
  407.      }
  408.   }
  409.  
  410.   /*** Initialise (or re-initialise) the Picture->Bitmap ***/
  411.  
  412.   Temp = Bitmap->Data;
  413.   Bitmap->Data = (APTR)-1; /* Fake the data pointer to prevent an allocation */
  414.   if (Init(Bitmap, NULL) IS NULL) {
  415.      DPrintF("!Query:","Could not initialise bitmap.");
  416.      goto exit;
  417.   }
  418.   Bitmap->Data = Temp;
  419.   error = ERR_OK;
  420.  
  421. exit:
  422.   if (Buffer) FreeMemBlock(Buffer);
  423.   if (BMHD)   FreeMemBlock(BMHD);
  424.   if (CMAP)   FreeMemBlock(CMAP);
  425.   if (FreeFile IS TRUE) Free(File);
  426.   StepBack();
  427.   return(error);
  428. }
  429.  
  430. /************************************************************************************
  431. ** Actions: File support.
  432. ** Object:  Picture
  433. ** Short:   These routines allow you to read/write to a Picture's Bitmap.
  434. */
  435.  
  436. LIBFUNC LONG PIC_Read(mreg(__a0) struct Picture *Picture, mreg(__a1) BYTE *Buffer, mreg(__d0) LONG Length) {
  437.   return(Read(Picture->Bitmap,Buffer,Length));
  438. }
  439.  
  440. LIBFUNC LONG PIC_Seek(mreg(__a0) struct Picture *Picture, mreg(__d0) LONG Offset, mreg(__d1) WORD Position) {
  441.   return(Seek(Picture->Bitmap,Offset,Position));
  442. }
  443.  
  444. LIBFUNC LONG PIC_Write(mreg(__a0) struct Picture *Picture, mreg(__a1) BYTE *Buffer, mreg(__d0) LONG Length) {
  445.   return(Write(Picture->Bitmap,Buffer,Length));
  446. }
  447.  
  448.